package com.lsh.oms.core.service.po;

import com.lsh.base.lang.bean.Beans;
import com.lsh.base.lang.json.Jsons;
import com.lsh.oms.core.dao.po.OmsTaskDao;
import com.lsh.oms.core.enums.TaskStatus;
import com.lsh.oms.core.enums.TaskType;
import com.lsh.oms.core.model.order.OrderSignHead;
import com.lsh.oms.core.model.po.OmsTask;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * Project Name: lsh-oms
 *
 * @author peter
 * @date 18/2/27
 * 北京链商电子商务有限公司
 * Package
 * desc:
 */
@Service
@Slf4j
public class OmsTaskService {

    private static final Logger LOGGER = LoggerFactory.getLogger(OmsTaskService.class);

    @Autowired
    private OmsTaskDao omsTaskDao;

    @Transactional(rollbackFor = Exception.class)
    public void addRepeatedHttpTrigger(Long id, Long venderId, Map<String, Object> request) {
        addHttpTrigger(TaskType.REPEATED_HTTP_TRIGGER, id, venderId, request);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addHttpTrigger(Long id, Long venderId, Map<String, Object> request) {
        addHttpTrigger(TaskType.HTTP_TRIGGER, id, venderId, request);
    }

    private void addHttpTrigger(TaskType type, Long id, Long venderId, Map<String, Object> request) {
        request = new HashMap<>(request);

        OmsTask task = new OmsTask();
        task.setTaskType(type.getCode());
        task.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
        task.setRefCode(id.toString());

        Map<String, Object> headers = Beans.getMap(request, "headers", new HashMap<>());
        Optional.ofNullable(MDC.get("trace-id")).ifPresent($ -> headers.put("X-Local-Trace-Id", $));
        request.put("headers", headers);

        task.setExt(Jsons.toJsonString(request));
        task.setVenderId(venderId);
        add(task);
        LOGGER.info("add task ref code: {}", task.getRefCode());
    }

    @Transactional(rollbackFor = Exception.class)
    public int add(OmsTask omsTask) {

        int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        omsTask.setCreateTime(time);
        omsTask.setUpdateTime(time);
        omsTask.setExecCount(0);
        if (omsTask.getTaskStatus() == null) {
            omsTask.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
        }

        return omsTaskDao.insertSelective(omsTask);
    }

    @Transactional(rollbackFor = Exception.class)
    public int update(OmsTask omsTask) {

        int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        omsTask.setUpdateTime(time);

        return omsTaskDao.updateByPrimaryKeySelective(omsTask);
    }

    @Transactional(rollbackFor = Exception.class)
    public int updateTaskAndAddExecCount(OmsTask omsTask) {

        int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        omsTask.setUpdateTime(time);
        omsTask.setExecCount(omsTask.getExecCount() + 1);

        return omsTaskDao.updateByPrimaryKeySelective(omsTask);
    }


    public List<OmsTask> getTasksByType(int taskType, int taskStatus) {

        OmsTask omsTask = new OmsTask();
        omsTask.setTaskType(taskType);
        omsTask.setTaskStatus(taskStatus);

        return this.getTasksByFilter(omsTask);
    }

    @Transactional(readOnly = true)
    public List<OmsTask> getTasksByFilter(OmsTask filter) {

        return omsTaskDao.selectByFilter(filter);
    }

    @Transactional(rollbackFor = Exception.class)
    public int setExclCount(Long taskId, Integer exclCount) {

        OmsTask omsTask = new OmsTask();
        int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());

        omsTask.setUpdateTime(time);
        omsTask.setExecCount(exclCount);
        omsTask.setId(taskId);

        return omsTaskDao.updateByPrimaryKeySelective(omsTask);
    }


    public OmsTask getTaskOneByFilter(OmsTask filter) {

        List<OmsTask> omsTaskList = this.getTasksByFilter(filter);

        if (omsTaskList == null) {
            return null;
        }

        if (omsTaskList.size() == 1) {
            return omsTaskList.get(0);
        } else {
            return null;
        }

    }

    public List<OmsTask> getTasks(Integer startTime, Integer endTime, Integer status) {

        List<OmsTask> omsTaskList = omsTaskDao.selectByStatusAndTime(startTime, endTime, status);

        if (omsTaskList == null) {
            return null;
        }

        return omsTaskList;

    }

    public List<OmsTask> getTasksByTypeAndStatuses(Integer taskType, List<Integer> taskStatus, Integer fetchSize) {

        return omsTaskDao.selectByTypeAndStatuses(taskType, taskStatus, fetchSize);
    }


    /**
     * @param oshUpdateList
     */
    public void add35Task(List<OrderSignHead> oshUpdateList) {

        try {
            for (OrderSignHead orderSignHead : oshUpdateList) {
                OmsTask filter = new OmsTask();
                filter.setRefCode(orderSignHead.getReceiptOrderId() + "");
                filter.setTaskType(TaskType.RECEIPT_TO_ACCOUNT.getCode());
                List<OmsTask> omsTasks = this.getTasksByFilter(filter);

                if (!CollectionUtils.isEmpty(omsTasks)) {
                    log.info("receipt_order_id select omsTasks size {} ", orderSignHead.getReceiptOrderId(), omsTasks.size());
                    continue;
                }

                OmsTask omsTask = new OmsTask();
                omsTask.setRefCode(orderSignHead.getReceiptOrderId() + "");
                omsTask.setTaskType(TaskType.RECEIPT_TO_ACCOUNT.getCode());
                omsTask.setVenderId(orderSignHead.getVenderId());
                this.add(omsTask);
            }
        } catch (Exception e) {
            log.error("35 添加task失败", e);
        }

    }

}
